home *** CD-ROM | disk | FTP | other *** search
-
- Free Information Xchange '97 presents:
-
- Virtua Fighter - CD Crack by Static Vengeance
-
- Requirements:
- Hex Editor and Full Install
-
-
- Ok, once again I set out to remove the CD check from a SEGA Entertainment game using W32Dasm
- from URSoft. Having already cracked two games by Sega (Daytona USA and Virtua Fighter 2) I thought
- this game would be striaght forward and fairly easy to do. However, just when you count on something
- being easy, it's not!.. So if you following along I'll show what I found and what I did to remove the
- CD check from this game. Also bear in mind that the program version I'm using is the updated DirectX
- v3b version of Virtua Fighter and not the version from the CD, although I have included a simular patch
- for that version also. Let's get going:
- Start up W32Dasm and 'Open file to disassemble' using vfpc.exe from where ever you installed it
- to. Once W32Dasm has finished it's process and is ready, go up to the title bar select 'Refs' and choose
- 'String data references'. From here grab the slider bar and scroll down looking at the strings.
- Eventually you find "Cannot find Virtua Fighter(TM) ". So double click on this and it puts you in the
- middle of the CD check routine. So let's take a look at the code:
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:00505544(C), :00505558(C)
- |
- :00505565 6A00 push 00000000
-
- * Possible StringData Ref from Data Obj ->"Virtua Fighter PC"
- |
- :00505567 68D0CFB000 push 00B0CFD0
-
- * Reference To: USER32.FindWindowA, Ord:00C8h
- |
- :0050556C FF1598F5BE00 Call dword ptr [00BEF598]
- :00505572 8945DC mov dword ptr [ebp-24], eax
- :00505575 837DDC00 cmp dword ptr [ebp-24], 00000000
- :00505579 0F8411000000 je 00505590
- :0050557F 8B45DC mov eax, dword ptr [ebp-24]
- :00505582 50 push eax
-
- * Reference To: USER32.BringWindowToTop, Ord:000Ah
- |
- :00505583 FF15A0F5BE00 Call dword ptr [00BEF5A0]
- :00505589 33C0 xor eax, eax
- :0050558B E9D2000000 jmp 00505662
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00505579(C)
- |
- :00505590 E87FCEEFFF call 00402414 <-- Check for file on CD
- :00505595 85C0 test eax, eax <-- Did it pass?
- :00505597 0F844A000000 je 005055E7 <-- Take this jump for a pass
-
- * Reference To: KERNEL32.GetOEMCP, Ord:00F6h <-- Otherwise tell EVIL user to insert CD
- |
- :0050559D FF15BCF4BE00 Call dword ptr [00BEF4BC]
- :005055A3 8945B0 mov dword ptr [ebp-50], eax
- :005055A6 817DB0A4030000 cmp dword ptr [ebp-50], 000003A4
- :005055AD 0F8519000000 jne 005055CC
- :005055B3 6A30 push 00000030
-
- * Possible StringData Ref from Data Obj ->"Virtua Fighter PC"
- |
- :005055B5 68D0CFB000 push 00B0CFD0
-
- * Possible StringData Ref from Data Obj ->"Virtua Fighter(TM) PC "
- |
- :005055BA 6820D0B000 push 00B0D020
- :005055BF 6A00 push 00000000
-
- * Reference To: USER32.MessageBoxA, Ord:0197h
- |
- :005055C1 FF1538F5BE00 Call dword ptr [00BEF538]
- :005055C7 E914000000 jmp 005055E0
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:005055AD(C)
- |
- :005055CC 6A30 push 00000030
-
- * Possible StringData Ref from Data Obj ->"Virtua Fighter PC"
- |
- :005055CE 68D0CFB000 push 00B0CFD0
-
- * Possible StringData Ref from Data Obj ->"Cannot find Virtua Fighter(TM) " <-- Seems like something we're
- ->"PC CD." <-- looking for, right?
- |
- :005055D3 68CCD0B000 push 00B0D0CC
- :005055D8 6A00 push 00000000
-
- * Reference To: USER32.MessageBoxA, Ord:0197h
- |
- :005055DA FF1538F5BE00 Call dword ptr [00BEF538]
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:005055C7(U)
- |
- :005055E0 33C0 xor eax, eax
- :005055E2 E97B000000 jmp 00505662
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00505597(C)
- |
- :005055E7 8B4510 mov eax, dword ptr [ebp+10]
- :005055EA 50 push eax
- :005055EB 8B4514 mov eax, dword ptr [ebp+14]
- :005055EE 50 push eax
- :005055EF 8B450C mov eax, dword ptr [ebp+0C]
- :005055F2 50 push eax
- :005055F3 8B4508 mov eax, dword ptr [ebp+08]
- :005055F6 50 push eax
- :005055F7 E815CCEFFF call 00402211
- :005055FC 83C410 add esp, 00000010
- :005055FF 85C0 test eax, eax
- :00505601 0F8507000000 jne 0050560E
- :00505607 33C0 xor eax, eax
- :00505609 E954000000 jmp 00505662
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00505601(C)
- |
- :0050560E C745E000000000 mov [ebp-20], 00000000
- :00505615 8D45E0 lea eax, dword ptr [ebp-20]
- :00505618 50 push eax
- :00505619 68301C4000 push 00401C30
-
- * Reference To: USER32.EnumWindows, Ord:00C3h
- |
- :0050561E FF15A4F5BE00 Call dword ptr [00BEF5A4]
- :00505624 837DE001 cmp dword ptr [ebp-20], 00000001
- :00505628 0F8E07000000 jle 00505635
- :0050562E 33C0 xor eax, eax
- :00505630 E92D000000 jmp 00505662
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00505628(C)
- |
- :00505635 A164395400 mov eax, dword ptr [00543964]
- :0050563A 50 push eax
- :0050563B 8B4514 mov eax, dword ptr [ebp+14]
- :0050563E 50 push eax
- :0050563F 8B4510 mov eax, dword ptr [ebp+10]
- :00505642 50 push eax
- :00505643 8B450C mov eax, dword ptr [ebp+0C]
- :00505646 50 push eax
- :00505647 8B4508 mov eax, dword ptr [ebp+08]
- :0050564A 50 push eax
- :0050564B E872CFEFFF call 004025C2
- :00505650 83C414 add esp, 00000014
- :00505653 8945EC mov dword ptr [ebp-14], eax
- :00505656 E888C7EFFF call 00401DE3
- :0050565B 33C0 xor eax, eax
- :0050565D E900000000 jmp 00505662
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:0050553B(U), :00505560(U), :0050558B(U), :005055E2(U), :00505609(U)
- |:00505630(U), :0050565D(U)
- |
- :00505662 5F pop edi
- :00505663 5E pop esi
- :00505664 5B pop ebx
- :00505665 C9 leave
- :00505666 C21000 ret 0010
-
- The first conditional branch before it prints "cannot find.." comes from 5055AD by way of
- listed reference at 5055CC.. so time to check out 5055AD and surounding code a little closer. We see
- the conditional branch/jump (jne) at 5055AD and a call to the KERNEL32.GetOEMCP... so back up some
- more... and you see at 505590 is a call, a test and a condition jump... this looks interesting...
- following the code you check out 402414 and will find it jumps to 4ACDF9. Alright, time to follow
- that section of code and try to see what it does:
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00402414(U)
- |
- :004ACDF9 55 push ebp
- :004ACDFA 8BEC mov ebp, esp
- :004ACDFC 81EC54010000 sub esp, 00000154
- :004ACE02 53 push ebx
- :004ACE03 56 push esi
- :004ACE04 57 push edi
-
- * Possible StringData Ref from Data Obj ->"rb"
- |
- :004ACE05 68C011B400 push 00B411C0
-
- * Possible StringData Ref from Data Obj ->"texture2.bin" <-- Check CD for this file
- |
- :004ACE0A 68C411B400 push 00B411C4
- :004ACE0F E89250F5FF call 00401EA6
- :004ACE14 83C404 add esp, 00000004
- :004ACE17 50 push eax
- :004ACE18 E823F90700 call 0052C740
- :004ACE1D 83C408 add esp, 00000008
- :004ACE20 8945FC mov dword ptr [ebp-04], eax
- :004ACE23 837DFC00 cmp dword ptr [ebp-04], 00000000
- :004ACE27 0F850A000000 jne 004ACE37
- :004ACE2D B801000000 mov eax, 00000001
- :004ACE32 E9B8000000 jmp 004ACEEF
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004ACE27(C)
- |
- :004ACE37 8B45FC mov eax, dword ptr [ebp-04]
- :004ACE3A 50 push eax
- :004ACE3B 6800010000 push 00000100
- :004ACE40 6A01 push 00000001
- :004ACE42 8D85ACFEFFFF lea eax, dword ptr [ebp+FFFFFEAC]
- :004ACE48 50 push eax
- :004ACE49 E812F90700 call 0052C760
- :004ACE4E 83C410 add esp, 00000010
- :004ACE51 8B45FC mov eax, dword ptr [ebp-04]
- :004ACE54 50 push eax
- :004ACE55 E826F80700 call 0052C680
- :004ACE5A 83C404 add esp, 00000004
-
- * Possible StringData Ref from Data Obj ->"\vfpc\vfrright.txt" <-- Path of file on CD to check for
- |
- :004ACE5D A1BC11B400 mov eax, dword ptr [00B411BC]
- :004ACE62 50 push eax
- :004ACE63 0FBE8548FFFFFF movsx eax, byte ptr [ebp+FFFFFF48]
- :004ACE6A 83C040 add eax, 00000040
- :004ACE6D 50 push eax
-
- * Possible StringData Ref from Data Obj ->"%c:%s"
- |
- :004ACE6E 68D411B400 push 00B411D4
- :004ACE73 8D45AC lea eax, dword ptr [ebp-54]
- :004ACE76 50 push eax
- :004ACE77 E824FD0700 call 0052CBA0
- :004ACE7C 83C410 add esp, 00000010
- :004ACE7F 6A00 push 00000000
- :004ACE81 8D45AC lea eax, dword ptr [ebp-54]
- :004ACE84 50 push eax
- :004ACE85 E856ED0800 call 0053BBE0
- :004ACE8A 83C408 add esp, 00000008
- :004ACE8D 85C0 test eax, eax <-- Here's a test
- :004ACE8F 0F850C000000 jne 004ACEA1 <-- Not equal, look again
- :004ACE95 33C0 xor eax, eax <-- Good, make eax = zero
- :004ACE97 E953000000 jmp 004ACEEF <-- jmp to end of routine
- :004ACE9C E94E000000 jmp 004ACEEF
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004ACE8F(C)
- |
-
- * Possible StringData Ref from Data Obj ->"\vfpc\vfrright.txt" <-- File on CD again...
- |
- :004ACEA1 A1BC11B400 mov eax, dword ptr [00B411BC]
- :004ACEA6 50 push eax
- :004ACEA7 0FBE8547FFFFFF movsx eax, byte ptr [ebp+FFFFFF47]
- :004ACEAE 83C040 add eax, 00000040
- :004ACEB1 50 push eax
-
- * Possible StringData Ref from Data Obj ->"%c:%s"
- |
- :004ACEB2 68DC11B400 push 00B411DC
- :004ACEB7 8D45AC lea eax, dword ptr [ebp-54]
- :004ACEBA 50 push eax
- :004ACEBB E8E0FC0700 call 0052CBA0
- :004ACEC0 83C410 add esp, 00000010
- :004ACEC3 6A00 push 00000000
- :004ACEC5 8D45AC lea eax, dword ptr [ebp-54]
- :004ACEC8 50 push eax
- :004ACEC9 E812ED0800 call 0053BBE0
- :004ACECE 83C408 add esp, 00000008
- :004ACED1 85C0 test eax, eax <-- Test again
- :004ACED3 0F850C000000 jne 004ACEE5 <-- not equal, then fail
- :004ACED9 33C0 xor eax, eax <-- good, set eax to zero
- :004ACEDB E90F000000 jmp 004ACEEF <-- jmp to end
- :004ACEE0 E90A000000 jmp 004ACEEF
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:004ACED3(C)
- |
- :004ACEE5 B801000000 mov eax, 00000001 <-- Force fail value (anything but zero)
- :004ACEEA E900000000 jmp 004ACEEF
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
- |:004ACE32(U), :004ACE97(U), :004ACE9C(U), :004ACEDB(U), :004ACEE0(U)
- |:004ACEEA(U)
- |
- :004ACEEF 5F pop edi
- :004ACEF0 5E pop esi
- :004ACEF1 5B pop ebx
- :004ACEF2 C9 leave
- :004ACEF3 C3 ret
-
- I guess that seems fairly straight forward... now that I had looked into it a bit. This little
- section of code is THE determining factor in the CD check:
-
- :00505590 E87FCEEFFF call 00402414 <-- Check for \vfpc\vfrright.txt on CD
- :00505595 85C0 test eax, eax <-- Test the results of the CD check
- :00505597 0F844A000000 je 005055E7 <-- eax=zero is good check
-
- Ok, now we have the code responsible for the CD check, and we see the test and the single
- conditional jump for a pass or fail of that check. The edit comes in the form of replacing the call
- with instructions to xor eax,eax (eXcluse OR eax to itself, which zeros out eax and would be the same
- as a good CD check) which makes the je (jump on equal (zero)) always true. Then fill in the remainder
- of bytes with NOP's (No OPeration) The actual edits for the crack depends on the version you have:
-
- CD file version EDIT vfpc.exe (offset 1,058,725)
- ================================================
- Search for: E8 9C F0 EF FF
- Change to : 33 C0 90 90 90
-
- dx3b update version EDIT vfpc.exe (offset 1,067,408)
- ====================================================
- Search for: E8 7F CE EF FF
- Change to : 33 C0 90 90 90
-
- Now you can play Virtua Fighter without putting the CD in the CD-ROM drive first, becuase
- you have just FiX'ed this game.
-
- Static Vengeance
-